//
// Created by 吳廣帥 on 2023/7/27.
// 1. 需要定时器1, 分频 72 - 1 向上计数
// 2. 引脚默认使用 PC14
// 3. 读取方式使用 两个 8位 2字节 数组, 调取DHT11_Read()方法即可
// 4. 读取函数返回值包含 0 , 1 , 2, 为1时读取数据生效

#include "dht11.h"
#include "gpio.h"
#include "tim.h"

/** 设输出模式 */
void Set_Pin_Output(){
    GPIO_InitTypeDef gpioInitTypeDef;
    gpioInitTypeDef.Pin = DHT11_GPIO_PIN;
    gpioInitTypeDef.Mode = GPIO_MODE_OUTPUT_PP;
    gpioInitTypeDef.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(DHT11_GPIO_PORT, &gpioInitTypeDef);
}
/** 设置输入模式 */
void Set_Pin_Input(){
    GPIO_InitTypeDef gpioInitTypeDef;
    gpioInitTypeDef.Pin = DHT11_GPIO_PIN;
    gpioInitTypeDef.Mode = GPIO_MODE_INPUT;
    gpioInitTypeDef.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(DHT11_GPIO_PORT, &gpioInitTypeDef);
}
/** 写数据 */
void White_Pin(GPIO_PinState pinState){
    HAL_GPIO_WritePin(DHT11_GPIO_PORT,DHT11_GPIO_PIN,pinState);
}
/** 读取针脚数据 */
int Read_Pin(){
    return HAL_GPIO_ReadPin(DHT11_GPIO_PORT,DHT11_GPIO_PIN);
}
/** us延迟函数 */
void Delay_us(int us){
    int count = 0;
    __HAL_TIM_SetCounter(&htim1,count);
    HAL_TIM_Base_Start(&htim1);
    while (count < us){
        count = __HAL_TIM_GetCounter(&htim1);
    }
    HAL_TIM_Base_Stop(&htim1);
}


/** 读取一位数据 */
int Read_Bit(){
    uint8_t retry = 0;
    while (Read_Pin() && retry < 254){
        retry++;
        Delay_us(20);
    }
    if(retry == 254) return 0;
    else retry = 0;
    while (!Read_Pin() && retry < 254) {
        retry++;
        Delay_us(20);
    }
    if(retry == 254) return 0;
    Delay_us(40);
    return Read_Pin();
}
/** 读取1字节数据 */
uint8_t Read_Byte(){
    uint8_t data = 0;
    for(int i = 0; i < 8; i++){
        data <<= 1;
        data |= Read_Bit();
    }
    return data;
}
/** 检测DHT11 */
uint8_t DHT11_Check_Sign(){
    Set_Pin_Input();
    uint8_t retry = 0;
    while (Read_Pin() && retry < 254){ // 判断有无信号波动
        retry++;
        Delay_us(20);
    }
    if(retry == 254) return ERROR_SIGN; // 无信号
    else retry = 0;
    while (!Read_Pin() && retry < 254){
        retry++;
        Delay_us(20);
    }
    return retry == 254 ? NO_SIGN : HAS_SIGN; // 计数结束, 无应答, 否则为信号正常, 之后可以进行读数据操作;
}

/**
 * 初始化读取数据
 */
void DHT11_Start(){
    Set_Pin_Output();
    White_Pin(0);
    HAL_Delay(20); // delay 20ms
    White_Pin(1);
    Delay_us(30);
}

/**
 * 读取传感器值
 * @param H
 * @param C
 */
uint8_t DHT11_Read(uint8_t *TEMP, uint8_t *RH){
    uint8_t buf[5];
    DHT11_Start();
    uint8_t res = DHT11_Check_Sign();
    if(res != 1) return res; // 检测失败
    for(uint8_t i = 0; i < 5; i++)  buf[i] = Read_Byte();
    if((buf[0] + buf[1] + buf[2] + buf[3] == buf[4])){
        TEMP[0] = buf[2];
        TEMP[1] = buf[3];
        RH[0] = buf[0];
        RH[1] = buf[1];
        return OK;
    }
    else return ERROR_COM;
}